<template>
  <div>
    <!-- 放置弹层组件 -->
    <!-- title 表示弹框标题 -->
    <!-- visible 控制弹框的隐藏显示 -->
    <!-- close-on-click-modal 点击遮罩不关闭 -->
    <!-- @open="getUserSimpleList"  open事件是弹框打开时触发 -->
    <el-dialog
      :title="showTitle"
      :visible="showDialog"
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <!-- 表单组件  el-form   label-width设置label的宽度   -->
      <!-- 匿名插槽 -->
      <el-form ref="addDeptForm" :model="formData" :rules="rules" label-width="120px">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="formData.name" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input v-model="formData.code" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="formData.manager" style="width:80%" placeholder="请选择">
            <el-option
              v-for="item in managerList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="formData.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" :rows="3" />
        </el-form-item>
      </el-form>
      <!-- el-dialog有专门放置底部操作栏的 插槽  具名插槽 -->
      <div slot="footer">
        <el-button type="primary" size="small" @click="confirmAddDept">确定</el-button>
        <el-button size="small" @click="closeDialog">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getUserSimpleListApi, addDepartmentApi, getDepartDetailApi, updateDepartmentsApi } from '@/api/departments'
export default {
// 需要传入一个props变量来控制 显示或者隐藏
  props: {
    showDialog: {
      type: Boolean,
      default: false
    },
    // 点击的一级数据  校验名字
    nodeData: {
      type: Object,
      // 复杂类型设置默认值 需要使用函数的方式
      default: () => {}
    },
    // 原始数据 校验编号
    deptsList: {
      type: Array,
      default: () => {}
    }
  },
  data() {
    return {
      formData: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '', // 部门介绍
        pid: ''// 添加部门的父级部门的id
      },
      rules: {
        name: [
          { required: true, message: '部门名称不可为空', trigger: 'blur' },
          { min: 1, max: 10, message: '部门名称的长度为1-10位', tigger: 'blur' },
          { validator: this.validateDeptName, tigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不可为空', trigger: 'blur' },
          { min: 1, max: 10, message: '部门编码的长度为1-10位', tigger: 'blur' },
          { validator: this.validateDeptCode, tigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不可为空', trigger: 'change' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      },
      //   部门负责人数据
      managerList: []

    }
  },
  computed: {
    showTitle() {
      return this.formData.id ? '编辑部门' : '新增部门'
    }
  },
  // created() {
  //  页面刷新的时候 就会进行接口请求 有点早了
  //   this.getUserSimpleList()
  // },
  methods: {
    /**
     * 点击关闭弹框时候  向父亲通信 父亲注册事件 关闭
     */
    closeDialog() {
      // this.$emit('closeDialogEmit') 旧方法
      this.$emit('update:showDialog', false)
      //   表单置空 因为编辑获取单独部门的时候  有很多信息赋值到了formData 所以重置一下
      this.formData = {
        name: '',
        code: '',
        manager: '',
        introduce: '',
        pid: ''
      }
      this.$refs.addDeptForm.resetFields()
      //   手动清除pid 因为pid没有再表单里
      this.formData.pid = ''
    },
    /**
     * 部门名称自定义校验
     */
    validateDeptName(rule, value, callback) {
      let children = []
      // 如果是编辑
      if (this.formData.id) {
        // 如果输入的值和点击的部门的名字一样
        if (this.nodeData.name === value) {
          // 校验成功并退出
          callback()
          return
        }
        // 如果名字不一样  那就找到跟点击部门的pid一致的，也就是兄弟部门 赋值给children
        children = this.deptsList.filter(item => this.nodeData.pid === item.pid)
        // 如果输入的值和点击的部门的名字不一样
      } else {
        // 如果是添加  拿到传过来的数据里的children
        children = this.nodeData.children || []
      }
      //   根据拿到的数据 遍历里面的每一项数据 看名字和输入的value是否一直 返回布尔值
      const result = children.some(item => item.name === value)
      //   三元 真的就返回错误 否则反之
      result ? callback(new Error('部门名称不能重复')) : callback()
    },
    /**
     * 部门编码自定义校验
     */
    validateDeptCode(rule, value, callback) {
      // 检测编码的时候，如果发现是编辑的时候 而且输入的编码和已有的数据有重复的也放行
      if (this.formData.id) {
        if (this.nodeData.code === value) {
          callback()
          return
        }
      }
      const result = this.deptsList.some(item => item.code === value)
      result ? callback(new Error('部门编码不能重复')) : callback()
    },
    /**
     * 打开弹框的时候 调用获取部门负责人的接口
     */
    async getUserSimpleList() {
      const { data } = await getUserSimpleListApi()
      // 获取的数据再给变量  变量传到el-select中进行遍历数据展示
      this.managerList = data
    },
    /**
     * 添加部门
     */
    confirmAddDept() {
      // 整体校验
      this.$refs.addDeptForm.validate(async flag => {
        // 失败退出
        if (!flag) return
        // 判断如果formData里有id 说明是编辑
        if (this.formData.id) {
          // 编辑
          await updateDepartmentsApi(this.formData)
          this.$message.success('编辑成功')
        } else {
          // 添加的确定
          // 将点击的部门的id  赋值给新增的pid  因为儿子的pid就是父亲的id
          this.formData.pid = this.nodeData.id
          // 调用新增接口 传入输入的数据
          await addDepartmentApi(this.formData)
          // 弹框
          this.$message.success('添加成功')
        }
        // 关闭弹框 清除数据
        this.closeDialog()
        // this.$parent.获取嵌套该组件的上级组件 再父组件里 可以获取方法属性
        this.$parent.getDepartmentList()
      })
    },
    /**
     * 获取单独的部门数据
     */
    async getDepartDetail(id) {
      const { data } = await getDepartDetailApi(id)
      this.formData = data
      // this.formData = data
    }
  }
}
</script>

<style>

</style>
